package RayTracing;

public class Vector {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//Testing Functions
		double[] a = {1, 3, -5};
		double[] b = {4, -2, -1};
		double[] v;
		double s;
		
		
		s = computeDotProduct(a,b);
		System.out.println("DotProduct: "  + s);
		v = computeCrossProduct(a,b);
		System.out.println("Cross: "  + v[0] + " " + v[1] + " " + v[2]);
		v = computeVectorAddition(a,b);
		System.out.println("Addition: "  + v[0] + " " + v[1] + " " + v[2]);
	}
	
	  public static double[] computeVectorAddition (double[] v0, double[] v1)
	  {
		    double vectorAddition[] = new double[3];
		    
		    vectorAddition[0] = v0[0] + v1[0];
		    vectorAddition[1] = v0[1] + v1[1];
		    vectorAddition[2] = v0[2] + v1[2];

		    return vectorAddition;
	  }
	  
	   public static double[][] transposeMatrix(double [][] m){
	        double[][] temp = new double[m[0].length][m.length];
	        for (int i = 0; i < m.length; i++)
	            for (int j = 0; j < m[0].length; j++)
	                temp[j][i] = m[i][j];
	        return temp;
	    }
	  
	  public static double[] computeVectorSubstraction (double[] v0, double[] v1)
	  {
		    double vectorAddition[] = new double[3];
		    
		    vectorAddition[0] = v0[0] - v1[0];
		    vectorAddition[1] = v0[1] - v1[1];
		    vectorAddition[2] = v0[2] - v1[2];

		    return vectorAddition;
	  }
	  
	  public static double[] computeVectorScalarAddition (double[] v0, double S)
	  {
		    double vectorAddition[] = new double[3];
		    
		    vectorAddition[0] = v0[0] + S;
		    vectorAddition[1] = v0[1] + S;
		    vectorAddition[2] = v0[2] + S;

		    return vectorAddition;
	  }
 
	  /**
	   * Compute the dot product (a scalar) between two vectors.
	   * 
	   * @param v0, v1  Vectors to compute dot product between [x,y,z].
	   * @return        Dot product of given vectors.
	   */
	  public static double computeDotProduct (double[] v0, double[] v1)
	  {
	    return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
	  }
	
	  
	  /**
	   * Compute the cross product (a vector) of two vectors.
	   * 
	   * @param v0, v1        Vectors to compute cross product between [x,y,z].
	   * @param crossProduct  Cross product of specified vectors [x,y,z].
	   */
	  public static double[] computeCrossProduct (double[] v0, double[] v1)
	  {
	    double crossProduct[] = new double[3];
	    
	    crossProduct[0] = v0[1] * v1[2] - v0[2] * v1[1];
	    crossProduct[1] = v0[2] * v1[0] - v0[0] * v1[2];
	    crossProduct[2] = v0[0] * v1[1] - v0[1] * v1[0];

	    return crossProduct;
	  }



	  /**
	   * Construct the vector specified by two points.
	   * 
	   * @param  p0, p1  Points the construct vector between [x,y,z].
	   * @return v       Vector from p0 to p1 [x,y,z].
	   */
	  public static double[] createVector (double[] p0, double[] p1)
	  {
	    double v[] = {p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]};
	    return v;
	  }
	  
	  public static double createNorm (double[] p0, double[] p1){
      
		double Norm = Math.sqrt(Math.pow(p0[0] - p1[0],2) + Math.pow(p0[1] - p1[1],2) + Math.pow(p0[2] - p1[2],2));

		return Norm;
	  }
	  
	  public static double[] createNormalizedVectorv(double[] p0, double[] p1){
			double[] Vector = createVector(p0, p1);
			double scalar = createNorm(p0, p1);
			
			Vector[0] =  Vector[0] / scalar ;
			Vector[1] =  Vector[1] / scalar ;
			Vector[2] =  Vector[2] / scalar;
			return Vector;
	  }
	  
	  public static double[] createNormalizedVectorv(double[] Vector){
		  	double[] zeroVector = new double[3];
			double scalar = createNorm(Vector, zeroVector);
			
			Vector[0] =  Vector[0] / scalar ;
			Vector[1] =  Vector[1] / scalar ;
			Vector[2] =  Vector[2] / scalar;
			return Vector;
	  }
	  
	    // return C = A * B
	    public static double[][] multiplyMatrix(double[][] A, double[][] B) {
	        int mA = A.length;
	        int nA = A[0].length;
	        int mB = B.length;
	        int nB = A[0].length;
	        if (nA != mB) throw new RuntimeException("Illegal matrix dimensions.");
	        double[][] C = new double[mA][nB];
	        for (int i = 0; i < mA; i++)
	            for (int j = 0; j < nB; j++)
	                for (int k = 0; k < nA; k++)
	                    C[i][j] += (A[i][k] * B[k][j]);
	        return C;
	    }

		public static double[] getPerpendicularVector(double[] v1, double[] v2) {
			double[] v;
			v = Vector.computeCrossProduct(v1, v2);
			v = Vector.createNormalizedVectorv(v);
			return v;
		}
	    
	    // matrix-vector multiplication (y = A * x)
	    public static double[] multiplyMatrixVector(double[][] A, double[] x) {
	        int m = A.length;
	        int n = A[0].length;
	        if (x.length != n) throw new RuntimeException("Illegal matrix dimensions.");
	        double[] y = new double[m];
	        for (int i = 0; i < m; i++)
	            for (int j = 0; j < n; j++)
	                y[i] += (A[i][j] * x[j]);
	        return y;
	    }
	    
	    public static double[] multiplyVectorbyScalar(double[] x, double S) {
		    double v[] = { x[0] * S, x[1] * S, x[2] * S};
		    return v;
	    }
	    

	
}


